#################################################################
#
#  Raspbuddies
#  University of Nantes
#  M2 -Alma
#  2012 - 2013
#
################################################################# 
#
#  Matthieu Allon - Pauline Folz - Teko Hemazro - Amine Lyazid
#  Adrien Quillet - Nicolas Rault - Kévin Simon
#
#################################################################

require "rubygems"
require "bud"

require 'causal.rb'
require 'broadcast.rb'
require 'neighbors.rb'
require 'HashModule.rb'
require 'Tests.rb'

module Debug
   private
   def lmapToArray(map)
      result = []
      (0..@vcSize-1).each do |i|
         result.insert(0, map.at(i).reveal)
      end
      return result.reverse
   end
   
   private
   def showNeighborsTable(table)
      result = "\tVoisinage : \n"
      table.each do |n|
         result = result + "\t\t" + n.inspect + "\n"
      end
      return result + "\n\n"
   end
   
   private
   def deliver()
      result = "\n\t\t"
      i = @name.delete("T").to_i
      (0..i).each do |t|
         result = result + "\t"
      end
      result = result + "(#{@budtime}) in T" + i.to_s + "\n\t\t"
      (0..i).each do |t|
         result = result + "\t"
      end
      return result
   end
   
   state do
      interface input, :pipe_poubelle, [:dst]
      channel :chn_poubelle, [:@dst]
   end
   
   bloom :debug do
      chn_poubelle <~ pipe_poubelle { |m| [m.dst] }
      stdio <~ bcast_send {|m| ["(#{@budtime}) #{@name} broadcast -- #{m.content} \n\t in #{name} message clock : #{lmapToArray(m.clock).inspect}"]}
      stdio <~ pipe_out {|m| ["#{deliver()}#{m.content}\n"]}
      stdio <~ chn {|c| ["(#{@budtime}) Inbound message in #{@name} from #{c.src} -- #{c.content} \n\t in message clock : #{lmapToArray(c.clock)} \n\t  in #{name} vc clock : #{lmapToArray(vc)} "]}
   end
end

module CausalBroadcast
   include CausalDelivery
   include Neighbors
   include Broadcast
   include Debug
   include HashFunctions
end

class CausalAgent
   include Bud
   include CausalBroadcast
   
   attr_reader :idProcess, :my_entries, :name
   
   def initialize(name, opts = {})
      @shareTime = 0.01
      @name = name
      @vcSize = 17
      @max = 10
      @actual = 0
      @select = 0
      @selectedNeighbor = ""
      
      super opts
   end
   
   def initProcess()
      @idProcess = ip_port
#       fi = {0=>[3,4], 1=>[13,9], 2=>[15,2], 3=>[5,13], 4=>[12,7]}
      fi = {0=>[3,4], 1=>[13,9], 2=>[15,2], 3=>[3,13], 4=>[12,7]}
#       fi = {0=>[0,1], 1=>[1,2], 2=>[2,3], 3=>[3,0], 4=>[12,7]}
# 	fi = {0=>[3,4], 1=>[9,13], 2=>[5,13], 3=>[9,4], 4=>[12,7]}
#         fi = {0=>[3,4], 1=>[9,13], 2=>[2,15], 3=>[5,13], 4=>[12,7]}
      @my_entries = fi[@name.delete("T").to_i]
      puts "\t" + @name + " = " + @idProcess.to_s + " : " + @my_entries.inspect
   end
end

def test()
   puts "------------------------------------------"
   puts "                Lancement"
   puts "------------------------------------------"
     
   t = Tests.new()
   t.init()
   t.test4()
        
   # CTRL + C pour interrompre
   interrupted = false
   
   trap("INT") { interrupted = true }
   
   while not interrupted
      sleep(0.5)
   end
   
   t.stopProcess()

   puts "------------------------------------------"
   puts "                   Fin"
   puts "------------------------------------------"
end

test()
